<template>
  <div id="mars3dContainer" class="mars3d-container"></div>
</template>

<script lang="ts" setup>
import { onMounted } from "vue";
import * as mars3d from "mars3d";
import * as Cesium from "mars3d-cesium";
import { bjgjJson } from "@/utils/bjgj";
import { busRoute } from "@/utils/busRoute";
import { getAssetsFile } from "@/utils";
let map: mars3d.Map; // 地图对象
let graphicLayer;
let tileLayer: any;
onMounted(() => {
  initMap();
  busLine();
  actualBus();
});
// 加载地图
const initMap = () => {
  let mapOptions = {
    scene: {
      center: { lat: 39.912925, lng: 116.381948, alt: 37540, heading: 359, pitch: -90 },
      highDynamicRange: false,
    },
    terrain: {
      show: false,
    },
    basemaps: [
      {
        name: "电子地图",
        icon: "img/basemaps/google_vec.png",
        type: "xyz",
        url:
          "https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}",
        show: true,
      },
    ],
  };
  map = new mars3d.Map("mars3dContainer", mapOptions);
  // 增加滤镜
  removeTileLayer();
  tileLayer = new mars3d.layer.GaodeLayer({
    layer: "vec",
    invertColor: true,
    filterColor: "#485468",
    brightness: 0.6,
    contrast: 1.8,
    gamma: 0.3,
    hue: 1,
    saturation: 0,
  });
  map.addLayer(tileLayer);
  // 创建矢量数据图层
  graphicLayer = new mars3d.layer.GraphicLayer();
  map.addLayer(graphicLayer);
};
// 移除滤镜
const removeTileLayer = () => {
  if (tileLayer) {
    map.removeLayer(tileLayer, true);
    tileLayer = null;
  }
};
// 北京公交线(OD线)
const busLine = () => {
  let data = bjgjJson;
  let busLines = [];
  data.forEach(function (busLine, idx) {
    let prevPt;
    const points = [];
    for (let i = 0; i < busLine.length; i += 2) {
      let pt = [busLine[i], busLine[i + 1]];
      if (i > 0) {
        pt = [prevPt[0] + pt[0], prevPt[1] + pt[1]];
      }
      prevPt = pt;

      const longitude = pt[0] / 1e4;
      const latitude = pt[1] / 1e4;
      const cart = Cesium.Cartesian3.fromDegrees(longitude, latitude, 100.0);
      points.push(cart);
    }
    busLines.push({
      positions: points,
      style: {
        width: 0.3,
        materialType: mars3d.MaterialType.LineFlow,
        image: getAssetsFile("lightFlow_strip07.png"),
        speed: 2 + 1.0 * Math.random(),
      },
    });
  });

  // 多个线对象的合并渲染。
  const graphic = new mars3d.graphic.PolylineCombine({
    instances: busLines,
  });
  graphicLayer.addGraphic(graphic);
};
// 北京公交汽车路线
const actualBus = () => {
  //处理数据
  busRoute.map((monomer) => {
    //绘制公交路线
    let positions = monomer.polyline.split(";");
    for (let i in positions) {
      let point = mars3d.PointTrans.gcj2wgs(positions[i].split(","));
      positions[i] = point.join(",");
    }
    let lineData = {
      positions,
      style: {
        width: 4,
        color: monomer.linecolor,
      },
    };
    const BusLine = new mars3d.graphic.PolylinePrimitive(lineData);
    graphicLayer.addGraphic(BusLine);
    //绘制公交停车点
    monomer.busstops.map((item, index) => {
      let point = mars3d.PointTrans.gcj2wgs(item.location.split(","));
      let positions = point.join(",");
      if (index === 0) {
        const startingPoint = new mars3d.graphic.BillboardPrimitive({
          position: positions,
          style: {
            image: getAssetsFile("origin.png"),
            horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            visibleDepth: false,
          },
        });
        graphicLayer.addGraphic(startingPoint);
      } else if (index === monomer.busstops.length - 1) {
        const endPoint = new mars3d.graphic.BillboardPrimitive({
          position: positions,
          style: {
            image: getAssetsFile("end.png"),
            horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            visibleDepth: false,
          },
        });
        graphicLayer.addGraphic(endPoint);
      } else {
        const BusPoints = new mars3d.graphic.PointPrimitive({
          position: positions,
          style: {
            color: "#fff",
            pixelSize: 5,
            label: {
              text: item.name,
              font_size: 12,
              color: "#19d5ff",
              pixelOffsetY: -20,
              background: true,
              backgroundPadding: 8,
              distanceDisplayCondition: true,
              distanceDisplayCondition_far: 5000,
              distanceDisplayCondition_near: 0,
            },
          },
        });
        graphicLayer.addGraphic(BusPoints);
      }
    });
    getSampledPositionProperty(positions);
  });
};
//绘制公交车行驶效果
const getSampledPositionProperty = (points: any) => {
  let speed = 20;
  let time = 0;
  let startTime = new Date();
  // 公交车的行驶路径
  let busPath = [
    {
      id: 1,
      x: points[0].split(",")[0],
      y: points[0].split(",")[1],
      z: 0,
      time: startTime.toISOString(),
    },
  ];
  // 公交车的发车时间
  for (let i in points) {
    if (i < points.length - 1) {
      let pointFirst = points[i].split(",");
      let pointSecond = points[Number(i) + 1].split(",");
      let positionLeft = Cesium.Cartesian3.fromDegrees(pointFirst[0], pointFirst[1]);
      let positionRight = Cesium.Cartesian3.fromDegrees(pointSecond[0], pointSecond[1]);
      let distance = Cesium.Cartesian3.distance(positionLeft, positionRight);
      time += (distance / 1000 / speed) * 3600 * 100;
      let currentTime = parseInt(startTime.getTime() + time * 100);
      let BusMoment = new Date(currentTime).toISOString();
      let vote = {
        id: i + 2,
        x: pointSecond[0],
        y: pointSecond[1],
        z: 0,
        time: BusMoment,
      };
      busPath.push(vote);
    }
  }
  const property = new Cesium.SampledPositionProperty();
  property.forwardExtrapolationType = Cesium.ExtrapolationType.HOLD;

  let start;
  let stop;
  for (let i = 0, len = busPath.length; i < len; i++) {
    const item = busPath[i];
    const lng = Number(item.x); // 经度
    const lat = Number(item.y); // 纬度
    const height = item.z; // 高度
    const time = item.time; // 时间

    let position = null;
    if (lng && lat) {
      position = Cesium.Cartesian3.fromDegrees(lng, lat, height);
    }
    let juliaDate = null;
    if (time) {
      juliaDate = Cesium.JulianDate.fromIso8601(time);
    }
    if (position && juliaDate) {
      property.addSample(juliaDate, position);
    }

    if (i === 0) {
      start = juliaDate;
    } else if (i === len - 1) {
      stop = juliaDate;
    }
  }

  // 设置时钟属性
  map.clock.startTime = start.clone();
  map.clock.stopTime = stop.clone();
  map.clock.currentTime = start.clone();
  map.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
  map.clock.multiplier = 5;

  if (map.controls.timeline) {
    map.controls.timeline.zoomTo(start, stop);
  }

  // 创建path对象
  let busPosition = new mars3d.graphic.PathEntity({
    position: property,
    orientation: new Cesium.VelocityOrientationProperty(property),
    style: {
      width: 0,
    },
    label: {
      text: busRoute[0].licence + "(" + busRoute[0].passengers + "人)",
      font_size: 12,
      background: true,
      backgroundColor: "#f7bd42",
      outline: true,
      outlineColor: "#fff",
      hasPixelOffset: true,
      pixelOffsetY: -20,
      distanceDisplayCondition: true,
      visibleDepth: false,
    },
    model: {
      url: "/model/bus.gltf",
      // heading: 360,
      fill: true,
      color: "#619e21",
      scale: 1,
      minimumPixelSize: 40,
    },
  });
  graphicLayer.addGraphic(busPosition);
};
// 实时公交时刻表
</script>

<style lang="scss" scoped>
.mars3d-container {
  width: 100vw;
  height: 100vh;
}
</style>
